package gnss

import (
	"dgo/goutils/utils"
	"fmt"
	"gitee.com/ymofen/gobase"
)

/*
*

	同步标记(0xD3) + 保留位(6(bit)) + 长度（RTCM消息体）(10bit)  (3 Byte)
	MsgID(12Bit) + 尾部标记(1Bit) + (3保留位) + DataBuf
	CRC24
*/
type GnssRtcmAnyBuf struct {
	MsgID   uint16
	Flag    byte // 0：尾包
	DataBuf []byte
}

func (this *GnssRtcmAnyBuf) CopyFrom(strMap gobase.StrMap) {
	this.DataBuf = []byte(strMap.URLFormEncode())
}

/*
**

	startBitN 从MsgID开始
*/
func DecodeGnssRtcmAny(rtcmAny *GnssRtcmAnyBuf, rtcmBuf []byte) {
	rtcmAny.MsgID = GetBitU16(rtcmBuf, 24, 12)
	rtcmAny.Flag = GetBitU8(rtcmBuf, 24+12, 1)
	rtcmAny.DataBuf = make([]byte, len(rtcmBuf)-3-2-3) //  头[3] + msgid[2]+crc[2]
	copy(rtcmAny.DataBuf, rtcmBuf[5:len(rtcmBuf)-3])
}

func EncodeGnssRtcmAnyBuf(rtcmAny *GnssRtcmAnyBuf) ([]byte, error) {
	if len(rtcmAny.DataBuf) > 1021 { // 1023-msgid
		return nil, fmt.Errorf("数据超过RTCM运行的长度:1021")
	}

	var bb gobase.BytesBuilder
	startIdx := 0
	bb.CheckSize(startIdx, 5) // 3 + len(DataBuf) + 3 end crc
	bb.Replace(startIdx, []byte{0xD3, 0, 0})

	byteN := 3
	bb.SetBitU16(startIdx+3, 0, 12, rtcmAny.MsgID)

	byteN += 2 // msgid

	bb.Write(rtcmAny.DataBuf)
	byteN += len(rtcmAny.DataBuf)

	// 长度
	bb.SetBitU16(startIdx, 14, 10, uint16(byteN-3)) // 长度

	crcBuf := bb.Buff(startIdx, byteN) // 3:同步标记 + 保留位 + 长度（RTCM消息体）(10bit)
	crc1 := utils.CRC24QBuf(crcBuf)

	bb.WriteBytes(0, 0, 0)
	bb.SetBitU32(startIdx+byteN, 0, 24, uint32(crc1))
	byteN += 3
	return bb.Bytes(), nil
}

func EncodeGnssRtcmAny(rtcmAny *GnssRtcmAnyBuf, bb *utils.BytesBuilder, startIdx int) (byteN int) {
	if len(rtcmAny.DataBuf) > 1021 { // 1023-msgid
		return 0
	}

	bb.CheckSize(startIdx, 5) // 3 + len(DataBuf) + 3 end crc
	bb.Replace(startIdx, []byte{0xD3, 0, 0})

	byteN = 3
	bb.SetBitU16(startIdx+3, 0, 12, rtcmAny.MsgID)

	byteN += 2 // msgid
	bb.Write(rtcmAny.DataBuf)
	byteN += len(rtcmAny.DataBuf)

	// 长度
	bb.SetBitU16(startIdx, 8+6, 10, uint16(byteN-3)) // 长度

	crcBuf := bb.Buff(startIdx, byteN) // 3:同步标记 + 保留位 + 长度（RTCM消息体）(10bit)
	crc1 := utils.CRC24QBuf(crcBuf)
	bb.WriteBytes(0, 0, 0)
	bb.SetBitU32(startIdx+byteN, 0, 24, uint32(crc1))
	byteN += 3
	return
}
